package com.wy2cloud.authorize.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import com.wy2cloud.authorize.handler.LoginSuccessHandler;
import com.wy2cloud.authorize.handler.UserLogoutSuccessHandler;
import com.wy2cloud.authorize.security.LoginUrlAuthenticationEntryPointAdapter;
import com.wy2cloud.authorize.service.UserDetailsServiceImpl;

/**
 * web安全配置
 * @author wuyy<16349023@qq.com>,nnsword
 * @date 2018年4月3日下午4:59:36
 *
 */
@Configuration
@EnableWebSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Autowired
    private UserDetailsServiceImpl userDetailsService;
    
    @Override
    @Bean // share AuthenticationManager for web and oauth
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http.antMatcher("/**").authorizeRequests().antMatchers("/static/**","/favicon.ico", "/login**", "/webjars/**",
                "/info/**",
                "/health/**",
                "/trace/**",
                "/configprops/**",
                "/metrics/**",
                "/loggers/**",
                "/env/**",
                "/dump/**",
                "/mappings/**").permitAll().anyRequest()
                .authenticated().and()
                .exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPointAdapter("/login")).and()
                .formLogin()
                    .loginPage("/login")
                    .defaultSuccessUrl("/")
                    .usernameParameter("username").passwordParameter("password")
                    .permitAll()
                    //登录成功后可使用loginSuccessHandler()存储用户信息，可选。
                    .successHandler(loginSuccessHandler())
                    .and()
                .logout()
                    .logoutUrl("/logout")
                    .logoutSuccessUrl("/login?logout")
                    .logoutSuccessHandler(logoutSuccessHandler())
                    .invalidateHttpSession(false)
                    .permitAll()
                    .and()
                .csrf().disable();
         //.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
                //.and()
                //.addFilterBefore(ssoFilter(), BasicAuthenticationFilter.class);
        // @formatter:on
    }
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.inMemoryAuthentication().withUser("admin")
//        .password("admin").roles("manage").authorities("read");
        
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
        auth.eraseCredentials(true); //擦除凭证，即密码
    }
    
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(4);
    }
    
    @Bean
    public LoginSuccessHandler loginSuccessHandler(){
        return new LoginSuccessHandler();//code6
    }
    @Bean
    public LogoutSuccessHandler logoutSuccessHandler(){
        return new UserLogoutSuccessHandler();//code6
    }
}
